package com.cdel.akka.chat;

import akka.actor.ActorRef;
import akka.actor.UntypedActor;
import akka.actor.ActorSystem;
import akka.actor.Props;

import java.util.HashMap;

public class RemoteChatServiceActor extends UntypedActor {

	private GuiServer chat;
	private HashMap<ActorRef, String> users;
	private Messages messages;

	/* constructor */
	public RemoteChatServiceActor(GuiServer chat) {
		this.chat = chat;
		messages = new Messages();
		users = new HashMap<>();
	}

	/* Server Behaviour */
	@Override
	public void onReceive(Object message) {

		switch (message.getClass().getSimpleName()) {

		case "LoginMessage":
			handleLoginMessage(message);
			break;

		case "LogoutMessage":
			handleLogoutMessage();
			break;

		case "ChatMessage":
			handleChatMessage(message);
			break;

		default:
			writeToLog("Messaggio non riconosciuto!...");
			break;

		}
	}

	/* update the log text-area */
	private void writeToLog(String logMessage) {
		this.chat.getLog().setText(this.chat.getLog().getText() + logMessage + "\n");
	}

	private void handleLoginMessage(Object message) {
		writeToLog(((Messages.LoginMessage)message).getNickname() + " login ok");
		users.put(getSender(), ((Messages.LoginMessage)message).getNickname());

		Messages.UserList userList = messages.new UserList(users.values().stream().toArray(String[]::new));

		for (ActorRef ref : users.keySet()){
			ref.tell(userList, getSelf());
		}
	}

	private void handleLogoutMessage() {
		writeToLog(users.get(getSender()) + " logout ok");
		users.remove(getSender());

		Messages.UserList userList = messages.new UserList(users.values().stream().toArray(String[]::new));

		// 先通知自己
		getSender().tell(messages.new UserList(new String[]{}), getSelf());
		for (ActorRef ref : users.keySet()){
			ref.tell(userList, getSelf());
		}
	}

	private void handleChatMessage(Object message) {
		writeToLog(users.get(getSender()) + " writes a message");

		Messages.ToPrintMessage toPrint = messages.new ToPrintMessage(users.get(getSender()) + "说：" + ((Messages.ChatMessage) message).getContent().trim());

		for (ActorRef ref : users.keySet()){
			ref.tell(toPrint, getSelf());
		}
	}

	/* _____STRAT the CHAT SERVER_____ */
	@SuppressWarnings("unused")
	public static void main(String[] args) {
		GuiServer frame = new GuiServer();
		frame.setVisible(true);
		frame.setLocationRelativeTo(null);
		frame.setTitle("Server - Akka Chat");

		final ActorSystem system = ActorSystem.create("ChatSystem");

		final ActorRef remoteActor = system.actorOf(Props.create(RemoteChatServiceActor.class, frame), "remoteActor");

		frame.printBootstrapMessage();
	}
}